package com.aizuda.boot.modules.flw.flow;

import cn.hutool.core.thread.ThreadUtil;
import com.aizuda.boot.modules.business.contract.entity.ContractEntity;
import com.aizuda.boot.modules.business.feishu.service.FeiShuApprovalService;
import com.aizuda.boot.modules.common.constant.enums.ContractStatusEnum;
import com.aizuda.boot.modules.common.constant.enums.NegotiationStatusEnum;
import com.aizuda.boot.modules.business.contract.mapper.ContractMapper;
import com.aizuda.boot.modules.business.negotiation.entity.ContractNegotiationInstanceEntity;
import com.aizuda.boot.modules.business.negotiation.mapper.ContractNegotiationInstanceMapper;
import com.aizuda.bpm.engine.core.FlowCreator;
import com.aizuda.bpm.engine.core.enums.InstanceEventType;
import com.aizuda.bpm.engine.entity.FlwHisInstance;
import com.aizuda.bpm.engine.listener.InstanceListener;
import com.aizuda.bpm.engine.model.NodeModel;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import java.util.function.Supplier;

/**
 * @Author sangyirong
 * @ClassName FlowInstaceListener
 * @Version 1.0
 * @Date 2025/8/1 12:56
 */
@Slf4j
@Component
@Primary
public class FlowInstanceListener implements InstanceListener {

    @Resource
    private ContractMapper contractmapper;

    @Resource
    private ContractNegotiationInstanceMapper contractNegotiationInstanceMapper;

    @Resource
    private FeiShuApprovalService feiShuApprovalService;

    @Override
    public boolean notify(InstanceEventType eventType, Supplier<FlwHisInstance> supplier, NodeModel nodeModel, FlowCreator flowCreator) {
        if (eventType == InstanceEventType.rejectComplete) {
            try {
                checkAndTerminateContract(supplier.get().getId());
            } catch (Exception e) {
                log.warn("终止合同审批失败，但不影响审批流程，合同: {}, 实例ID: {}", supplier.get().getBusinessKey(), supplier.get().getId(), e);
            }
        }
        ThreadUtil.execute(() -> {
            if (InstanceEventType.end.eq(eventType) || InstanceEventType.rejectComplete.eq(eventType)) {
                // 流程结束
                feiShuApprovalService.terminateApproval(eventType, supplier, flowCreator);
            }
        });
        return true;
    }


    private void checkAndTerminateContract(Long instanceId) {
        log.info("流程开始终止，开始检查并终止合同");
        if (null == instanceId) {
            log.warn("流程实例ID为空，无法终止合同");
        }
        if (checkContractApprovalAssociation(instanceId)) {
            try {
                Boolean terminated = terminateContractApproval(instanceId);
                if (terminated) {
                    log.info("审批实例终止成功，流程实例ID：{}", instanceId);
                    return;
                } else {
                    log.warn("审批实例终止失败，流程实例ID：{}", instanceId);
                }
            } catch (Exception e) {
                log.error("审批实例终止失败，流程实例ID：{}", instanceId, e);
            }
        }

        if (checkNegotiationApprovalAssociation(instanceId)) {
            try {
                Boolean terminated = terminateNegotiationApproval(instanceId);
                if (terminated) {
                    log.info("审核实例终止成功，流程实例ID：{}", instanceId);
                    return;
                } else {
                    log.warn("审核实例终止失败，流程实例ID：{}", instanceId);
                }
            } catch (Exception e) {
                log.error("审核实例终止失败，流程实例ID：{}", instanceId, e);
            }
        }


    }

    /**
     * 检查是否有关联的合同审批
     *
     * @param instanceId 流程实例ID
     * @return true 如果有关联的合同审批，false 如果没有
     */
    private boolean checkContractApprovalAssociation(Long instanceId) {
        if (instanceId == null) {
            return false;
        }
        ContractEntity contract = contractmapper.selectOne(Wrappers.<ContractEntity>lambdaQuery()
                .eq(ContractEntity::getApprovalInstanceId, instanceId)
                .orderByDesc(ContractEntity::getCreatedAt)
                .last("limit 1"));
        return contract != null;
    }

    /**
     * 检查是否有关联的协商审批
     *
     * @param instanceId 流程实例ID
     * @return true 如果有关联的协商审批，false 如果没有
     */
    private boolean checkNegotiationApprovalAssociation(Long instanceId) {
        if (instanceId == null) {
            return false;
        }
        ContractNegotiationInstanceEntity negotiationInstance = contractNegotiationInstanceMapper.selectOne(Wrappers.<ContractNegotiationInstanceEntity>lambdaQuery()
                .eq(ContractNegotiationInstanceEntity::getProcessInstanceId, instanceId)
                .orderByDesc(ContractNegotiationInstanceEntity::getCreatedAt)
                .last("limit 1"));
        return negotiationInstance != null;
    }

    /**
     * 终止合同审批
     */
    private boolean terminateContractApproval(Long instanceId) {
        ContractEntity contract = contractmapper.selectOne(Wrappers.<ContractEntity>lambdaQuery()
                .eq(ContractEntity::getApprovalInstanceId, instanceId)
                .orderByDesc(ContractEntity::getCreatedAt)
                .last("limit 1"));

        if (contract != null) {
            try {
                contract.setCurrentStatus(ContractStatusEnum.TERMINATED.getCode());
                int updated = contractmapper.updateById(contract);
                if (updated > 0) {
                    log.info("合同终止成功，合同ID：{}，流程实例ID：{}", contract.getId(), instanceId);
                    return true;
                } else {
                    log.warn("合同状态更新失败，合同ID：{}，流程实例ID：{}", contract.getId(), instanceId);
                }
            } catch (Exception e) {
                log.error("更新合同状态失败，合同ID：{}，流程实例ID：{}", contract.getId(), instanceId, e);
            }
        }
        return false;
    }

    /**
     * 终止协商审批
     */
    private boolean terminateNegotiationApproval(Long instanceId) {
        ContractNegotiationInstanceEntity negotiationInstance = contractNegotiationInstanceMapper.selectOne(
                Wrappers.<ContractNegotiationInstanceEntity>lambdaQuery()
                        .eq(ContractNegotiationInstanceEntity::getProcessInstanceId, instanceId)
                        .orderByDesc(ContractNegotiationInstanceEntity::getCreatedAt)
                        .last("limit 1"));

        if (negotiationInstance != null) {
            try {
                // 更新协商状态
                negotiationInstance.setNegotiationStatus(NegotiationStatusEnum.NEGOTIATION_CANCELED.getCode());
                int negotiationUpdated = contractNegotiationInstanceMapper.updateById(negotiationInstance);

                if (negotiationUpdated > 0) {
                    // 更新关联合同状态
                    ContractEntity contract = contractmapper.selectById(negotiationInstance.getContractId());
                    if (contract != null) {
                        contract.setCurrentStatus(ContractStatusEnum.TERMINATED.getCode());
                        int contractUpdated = contractmapper.updateById(contract);
                        if (contractUpdated > 0) {
                            log.info("协商审批终止成功，协商实例ID：{}，合同ID：{}，流程实例ID：{}",
                                    negotiationInstance.getId(), contract.getId(), instanceId);
                            return true;
                        } else {
                            log.warn("协商关联合同状态更新失败，合同ID：{}", contract.getId());
                        }
                    } else {
                        log.warn("协商关联的合同不存在，合同ID：{}", negotiationInstance.getContractId());
                    }
                } else {
                    log.warn("协商实例状态更新失败，协商实例ID：{}", negotiationInstance.getId());
                }
            } catch (Exception e) {
                log.error("更新协商状态失败，协商实例ID：{}，流程实例ID：{}",
                        negotiationInstance.getId(), instanceId, e);
            }
        }
        return false;
    }
}
